package com.zunipe.ftpe;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zunipe.ftpe.util.ZI18n;
import com.zunipe.ftpe.util.ZLog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

public class FTPConfig {
    private static final String TAG = "FTPConfig";

    private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
    private static final File configDir = new File(Constants.CONFIG_PATH);
    private static final File configFile = new File(Constants.CONFIG_PATH + File.separator + "config.json");
    private Config config;

    private static FTPConfig instance;

    public static FTPConfig getInstance() throws IOException {
        if (instance == null) {
            instance = new FTPConfig();
        }
        return instance;
    }

    private FTPConfig() throws IOException {
        readConfig();
    }

    public String getMatchingFormat() {
        return config.getMatchingFormat();
    }

    public void setMatchingFormat(String matchingFormat) throws IOException {
        config.setMatchingFormat(matchingFormat);
        saveConfig();
    }

    public void addPath(String path) throws IOException {
        config.addPath(path);
        saveConfig();
    }

    public void removePath(String path) throws IOException {
        List<String> paths = config.getPaths();
        paths.remove(path);
        saveConfig();
    }

    public void removeTimepoint(String timepoint) throws IOException {
        List<String> timePoints = config.getTimePoints();
        timePoints.remove(timepoint);
        saveConfig();
    }

    public void addTimepoint(String timepoint) throws IOException {
        List<String> timePoints = config.getTimePoints();
        timePoints.add(timepoint);
        saveConfig();
    }

    public boolean containsDownloadedFile(String fileName) {
        return config.getDownloadedFile().contains(fileName);
    }

    public void addDownloadedFile(String fileName) throws IOException {
        List<String> downloadedFile = config.getDownloadedFile();
        downloadedFile.add(fileName);
        saveConfig();
    }

    public String printConfig() {
        return config.toString();
    }

    public String getHostname() {
        return config.getHostname();
    }

    public int getPort() {
        return config.getPort();
    }

    public String getUsername() {
        return config.getUsername();
    }

    public String getPassword() {
        return config.getPassword();
    }

    public List<String> getPaths() {
        return config.getPaths();
    }

    public List<String> getTimePoints() {
        return config.getTimePoints();
    }

    public void readConfig() throws IOException {
        initConfig();
        config = gson.fromJson(new FileReader(configFile), Config.class);
    }

    private void saveConfig() throws IOException {
        String json = gson.toJson(config, Config.class);
        writeConfig(json);
    }

    private void writeConfig(String json) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(configFile)) {
            fos.write(json.getBytes());
        }
    }

    private void initConfig() throws IOException {
        boolean initFlag = false;
        if (!configDir.exists()) {
            if (!configDir.mkdirs()) {
                ZLog.e(TAG, ZI18n.getString("config.error.failed_create_directory"));
                throw new IOException("Failed to create configuration directory");
            }
            initFlag = true;
        }
        if (!configFile.exists()) {
            if (!configFile.createNewFile()) {
                ZLog.e(TAG, ZI18n.getString("config.error.failed_create_file"));
                throw new IOException("Failed to create configuration file");
            }
            initFlag = true;
        }
        if (initFlag) {
            Scanner sc = new Scanner(System.in);
            System.out.println(ZI18n.getString("config.info.tutorial_info"));
            System.out.print(ZI18n.getString("config.info.hostname"));
            String hostname = sc.nextLine();
            System.out.print(ZI18n.getString("config.info.port"));
            String port = sc.nextLine();
            System.out.print(ZI18n.getString("config.info.username"));
            String username = sc.nextLine();
            System.out.print(ZI18n.getString("config.info.password"));
            String password = sc.nextLine();
            System.out.print(ZI18n.getString("config.info.matching_format"));
            String matchingFormat = sc.nextLine();
            System.out.print(ZI18n.getString("config.info.path"));
            String path = sc.nextLine();
            Config config = new Config(hostname, Integer.parseInt(port), username, password, matchingFormat);
            config.addPath(path);
            String json = gson.toJson(config, Config.class);
            writeConfig(json);
        }
    }
}
